package cn.witsky.rtp2ws.domain;

import java.io.File;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.witsky.rtp2ws.Server;
import cn.witsky.rtp2ws.constant.ThreadPoolConstant;
import cn.witsky.rtp2ws.util.DefaultThreadFactory;
import cn.witsky.rtp2ws.util.LogUtil;
import cn.witsky.rtp2ws.util.SystemClock;

public class CallInfo extends BaseCall {
	private static ScheduledExecutorService schedule = Executors.newScheduledThreadPool(20,new DefaultThreadFactory(ThreadPoolConstant.callFinish));
	private static Logger logger = LoggerFactory.getLogger(CallInfo.class);
	private Rtp caller =null;
	private Rtp called =null;	
	private AtomicInteger rtpCount=null;
	private int taskIndex;
	private long finishTime=-1;
	private volatile long reciveByteTime=-1;
	
	public boolean hasPcm() {
		if(Server.isCompress()) {
			File callerFile=new File(Server.backUpRtpFileDir+"/"+caller.getPcmTarName());
			File calledFile=new File(Server.backUpRtpFileDir+"/"+called.getPcmTarName());
			return callerFile.exists()&&calledFile.exists();
		}else {
			File callerFile=new File(Server.backUpRtpFileDir+"/"+caller.getPcmName());
			File calledFile=new File(Server.backUpRtpFileDir+"/"+called.getPcmName());
			return callerFile.exists()&&calledFile.exists();
		}

	}
	
	public void resetRtpCount() {
		caller.finished();
		called.finished();
	}
	
	public AtomicInteger getRtpCount() {
		return rtpCount;
	}

	public CallInfo(String callId) {
		super(callId);
		rtpCount=new AtomicInteger(2);
		caller = new Rtp(this,true);
		called = new Rtp(this,false);	
	}
	
	public Rtp getRtp(boolean isCaller) {
		if(isCaller) {
			return caller;
		}else {
			return called;
		}
	}
	
	public void offerMessage(String source,int dstPort,int seq,byte[] payload) {
		boolean isCaller=true;
		Rtp rtp=null;
		if(dstPort!=this.getUdpPort()) {
			isCaller=false;
		}
		rtp=this.getRtp(isCaller);
		if(rtp.isFinished()) {
			LogUtil.warn(rtp, "offerMessage-67", "CallInfo[offerMessage:67] task:{}任务已经结束了,不处理source:{}的rtp数据流了",rtp.getRtpId(),source);
			return;
		}
		if(seq<0) {
			LogUtil.warn(rtp, "offerMessage-71", "CallInfo[offerMessage:71] task:{},无效的seq:{}不处理source:{}的rtp数据流了",rtp.getRtpId(),seq,source);
			return;
		}
		rtp.setSource(source);
		if(!Server.sendWsSync) {
			rtp.offerRtpData(seq, payload);
		}else {
			rtp.offerRtpDataSync(seq, payload);
		}		
	}
	public void offerMessage(String source,boolean isCaller,int seq,byte[] payload) {
		Rtp rtp=this.getRtp(isCaller);
		rtp.setSource(source);
		if(!Server.sendWsSync) {
			rtp.offerRtpData(seq, payload);
		}else {
			rtp.offerRtpDataSync(seq, payload);
		}		
	}
	
	public int getTaskIndex() {
		return taskIndex;
	}

	public void setTaskIndex(int taskIndex) {
		this.taskIndex = taskIndex;
	}
	
	public void setFinishTime(boolean delay) {
		logger.debug("call:{} setFinishTime",this.getCallId());
		if(this.finishTime<0) {
			synchronized (this) {
				if(this.finishTime>0) {
					return;
				}
				this.finishTime=SystemClock.now();
				if(delay) {
					final String taskId=this.getCallId();
					schedule.schedule(new Runnable() {					
						@Override
						public void run() {			
							try {
								caller.setFinishTime(finishTime);
								called.setFinishTime(finishTime);							
							}catch(Exception ex) {
								logger.error("call"+taskId+"延迟执行setFinishTime出现异常:",ex);
							}						
						}
					}, 200, TimeUnit.MILLISECONDS);
				}else {
					caller.setFinishTime(finishTime);
					called.setFinishTime(finishTime);	
				}				
			}
		}
	}
	public Long getFinishTime() {
		return finishTime;
	}
	public long getReciveByteTime() {
		return reciveByteTime;
	}
	public void setReciveByteTime() {
		this.reciveByteTime = SystemClock.now();
	}
	
}
